package com.zsk.shop.common.utils;

import com.alibaba.fastjson.JSON;
import com.zsk.shop.common.json.JSONObject;
import com.zsk.shop.model.results.HalfDateInfoResult;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 时间转换工具类
 *
 * @author yuwenbo
 * @version $Id: DateUtils.java, v 0.1 2017/6/5 18:15 yulijun Exp $$
 */
public class DateUtils {
    public static final String DEFAULT = "yyyy-MM-dd";
    public static final String YYYYMMDD = "yyyy-MM-dd";
    public static final String YYYYMMDD_SIMPLE = "yyyyMMdd";
    public static final String YYYYMM = "yyyy-MM";
    public static final String YYYYMM_STRING = "yyyyMM";
    public static final String YYYYMMDD_NO_SEPARATOR = "yyyyMMdd";
    public static final String YYYYMMDDHH = "yyyy-MM-dd HH";
    public static final String YYYYMMDDHHMM = "yyyy-MM-dd HH:mm";
    public static final String YYYYMMDDHHMMSS1 = "yyyyMMddHHmmss";
    public static final String YYYYMMDD000000 = "yyyy-MM-dd 00:00:00";
    public static final String YYYYMMDD0000001 = "yyyy-MM-dd 23:59:59";
    public static final String YYYYMMDDHH0000 = "yyyy-MM-dd HH:00:00";
    public static final String YYYYMMDDHHMM00 = "yyyy-MM-dd HH:mm:00";
    public static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String MMDDHHMM = "MM-dd HH:mm";
    public static final String MMDDHHMMSS = "MM-dd HH:mm:ss";
    public static final String MMddHHmm = "MMddHHmm";
    public static final String MMdd = "MMdd";
    public static final String YYYYMMddHHmm = "yyyyMMddHHmm";
    public static final String CHN_YMD_HHMM = "yyyy年MM月dd日 HH:mm";
    public static final String CHN_YMD = "yyyy年MM月dd日";
    public static final String CHN_YM = "yyyy年MM月";
    public static final String CHN_YMD_HH = "yyyy-MM-dd HH时";
    public static final String CHN_MDHHMM = "MM月dd日HH时mm分";
    public static final String CHN_MD = "MM月dd日";
    public static final String MMDD = "MM-dd";
    public static final String HHMMSS = "HH:mm:ss";

    private static final String[] WEEK_DAY = new String[]{"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};

    private static final ThreadLocal<SimpleDateFormat> yyyyMMdd = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    private static final ThreadLocal<SimpleDateFormat> yyyyMMddHHmmss = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    private static final ThreadLocal<SimpleDateFormat> yyyyMM = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM"));
    private static final ThreadLocal<SimpleDateFormat> yyyy_MM_dd = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy 年 MM 月 dd 日"));
    private static final ThreadLocal<SimpleDateFormat> yyyy = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy"));
    private static final ThreadLocal<SimpleDateFormat> MM = ThreadLocal.withInitial(() -> new SimpleDateFormat("MM"));
    private static final ThreadLocal<SimpleDateFormat> dd = ThreadLocal.withInitial(() -> new SimpleDateFormat("dd"));

    public static final Long tokenHours = 30 * 60 * 1000L * 24 * 365;

    /**
     * date转换成string
     *
     * @param date    Date对象
     * @param pattern 转换格式
     * @return
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    public static Timestamp getDateStart(String dateStart) {
        Date date = null;
        try {
            date = yyyyMMdd.get().parse(dateStart);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    public static Timestamp getDateEnd(String dateEnd) {
        Date date = null;
        try {
            date = yyyyMMdd.get().parse(dateEnd);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * date转换成string
     *
     * @param date Date对象
     * @return
     */
    public static String format(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(YYYYMMDDHHMMSS);
        return sdf.format(date);
    }

    /**
     * Calendar转换成string
     *
     * @param calendar Calendar对象
     * @param pattern  转换格式
     * @return
     */
    public static String format(Calendar calendar, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(calendar.getTime());
    }

    /**
     * string转换string
     */
    public static String parse2String(String datestring, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.format(sdf.parse(datestring));
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * string转换string
     */
    public static String parseString(String datestring, String pattern, String afterPattern) {
        return format(parse2Date(datestring, pattern), afterPattern);
    }

    public static int getMonth(String dateString) {
        Calendar now = Calendar.getInstance();
        Date date = parse2Date(dateString, YYYYMM);
        now.setTime(date);
        return now.get(Calendar.MONTH) + 1;
    }

    /**
     * string转换Date
     *
     * @param datestring 日期格式字符串
     * @param pattern    转换格式
     * @return Date对象
     */
    public static Date parse2Date(String datestring, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(datestring);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * string转换string
     */
    public static String parse2String(String datestring) {
        return format(parse2Date(datestring, YYYYMMDD_SIMPLE), YYYYMMDD);
    }

    /**
     * string转换Calender
     *
     * @param datestring 日期格式字符串
     * @param pattern    转换格式
     * @return Calendar对象
     */
    public static Calendar parse2Calendar(String datestring, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(sdf.parse(datestring));
            return calendar;
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取传入时间所属月的首日
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDayOfMonth = calendar.getTime();
        return firstDayOfMonth;
    }

    /**
     * 获取传入时间所属月的末尾日
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date lastDayOfMonth = calendar.getTime();
        return lastDayOfMonth;
    }

    /**
     * 往后倒退年份
     *
     * @return
     */
    public static Date getBackYear(Integer num) {
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        Integer month = calendar.get(Calendar.MONTH);
        calendar.set(year - num, month, 1);
        return calendar.getTime();
    }

    /**
     * 往后倒退年份到12月31日
     *
     * @return
     */
    public static Date getBackEndYear(Integer num) {
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        calendar.set(year - num, Calendar.DECEMBER, 31);
        return calendar.getTime();
    }

    /**
     * 往后倒退年份到1月1日
     *
     * @return
     */
    public static Date getBackStartYear(Integer num) {
        Calendar calendar = Calendar.getInstance();
        Integer year = calendar.get(Calendar.YEAR);
        calendar.set(year - num, Calendar.JANUARY, 1);
        return calendar.getTime();
    }

    /**
     * 往前倒退num天
     *
     * @return
     */
    public static Date getBackDay(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -num);
        return calendar.getTime();
    }

    /**
     * 往前倒退num天
     *
     * @return
     */
    public static String getBackDayStr(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, -num);
        return format(calendar.getTime(), YYYYMMDD);
    }

    /**
     * 添加月份
     *
     * @return
     */
    public static Date addMonth(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONDAY, num);
        return calendar.getTime();
    }

    public static Date addYear(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, num);
        return calendar.getTime();
    }

    /**
     * 添加天数
     *
     * @return
     */
    public static Date addDay(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, num);
        return calendar.getTime();
    }

    public static Date addDayOfDate(Date date, Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, num);
        return calendar.getTime();
    }

    public static void main(String[] args) {
        System.out.println(addDayOfDate(new Date(), -1));
        System.out.println(format(addDayOfDate(new Date(), -1), YYYYMMDD));
        System.out.println(getDateEnd(addDayOfDate(new Date(), -1)));
        System.out.println(getDateStart(addDayOfDate(new Date(), -1)));
    }

    /**
     * 在原有时间上 添加小时数
     *
     * @return
     */
    public static Date addHourOfDate(Date date, Integer num) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR_OF_DAY, num);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * 在当前时间 添加小时数
     *
     * @return
     */
    public static Date addHour(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, num);
        return calendar.getTime();
    }

    /**
     * 在原有时间上 添加分钟数
     *
     * @return
     */
    public static Date addMinuteOfDate(Date date, Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, num);
        Date newDate = calendar.getTime();
        return newDate;
    }

    /**
     * 在当前时间 添加分钟数
     *
     * @return
     */
    public static Date addMinute(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, num);
        return calendar.getTime();
    }

    public static String addDayString(Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, num);
        return format(calendar.getTime(), YYYYMMDD_SIMPLE);
    }

    /**
     * 添加天数
     *
     * @return
     */
    public static Date addDay(String dateString, Integer num) {
        Date date = parse2Date(dateString, YYYYMMDD);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, num);
        return calendar.getTime();
    }

    /**
     * 添加月份
     *
     * @return
     */
    public static Date addMonth(Date date, Integer num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONDAY, num);
        return calendar.getTime();
    }

    /**
     * 将日期时间归至零点
     *
     * @param date
     * @return
     */
    public static Date dateToBeginOfDay(Date date) {
        if (date != null) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            return calendar.getTime();
        }
        return null;
    }

    /**
     * 获取当前时间到第二天凌晨的时间间隔
     *
     * @return
     */
    public static Long getSecondsNextEarlyMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }

    /**
     * 秒转成天数
     *
     * @param mm
     * @return
     */
    public static Long convert2Day(Long mm) {
        if (null == mm) {
            return 0L;
        }
        Long day = mm / (60 * 60 * 24);
        return day;
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        long i = convert2Day((date2.getTime() - date1.getTime()) / 1000);
        return (int) i;
    }

//    public static void main(String[] args) throws Exception {
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        String date = "2021-03-19 19:00:00";
//        System.out.println(DateUtils.differentMs(new Date(), format.parse(date)) / 60);
//    }

    /**
     * 通过时间秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static long differentMs(Date date1, Date date2) {
        long i = (date2.getTime() - date1.getTime()) / 1000;
        return i;
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @return
     */
    public static long differentMs(Date date, String amount) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);
        gc.add(12, Integer.valueOf(amount));
        return differentMs(new Date(), gc.getTime());
    }

    /**
     * 天数转成秒数
     *
     * @param day
     * @return
     */
    public static Long convert2mill(Long day) {
        if (null == day) {
            return 0L;
        }
        return day * 24 * 60 * 60;
    }

    /**
     * 获得月的结束时间
     *
     * @param date
     * @return
     */
    public static Date getMonthEndTime(Date date) {
        return DateUtils.parse2Date(format(getLastDayOfMonth(date), YYYYMMDD0000001), YYYYMMDDHHMMSS);
    }

    /**
     * 获得月的开始时间
     *
     * @param date
     * @return
     */
    public static String getMonthStartTimeStr(Date date) {
        return format(getFirstDayOfMonth(date), YYYYMMDD);
    }

    /**
     * 获得月的结束时间
     *
     * @param date
     * @return
     */
    public static String getMonthEndTimeStr(Date date) {
        return format(getLastDayOfMonth(date), YYYYMMDD);
    }

    /**
     * 在指定时间上加特定的天数
     *
     * @param days 天数
     * @param date 指定的时间
     * @return
     */
    public static Date plusDay(int days, Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        return calendar.getTime();
    }

    /**
     * 获得本周一
     *
     * @param date 当前时间
     * @return
     */
    public static String getThisWeekStart(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        return format(cal.getTime(), YYYYMMDD);
    }

    /**
     * 本周末
     *
     * @param date
     * @return
     */
    public static String getThisWeekEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 == dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day + 6);
        return format(cal.getTime(), YYYYMMDD);
    }

    /**
     * 获得上周一时间
     *
     * @param date 当前时间
     * @return
     */
    public static Date geLastWeekMonday(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -7);
        return cal.getTime();
    }

    /**
     * 给时间加上几个小时
     *
     * @param date
     * @param hour 需要加的时间
     * @return
     */
    public static Date dateAddHour(Date date, int hour) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.HOUR, hour);
        return cal.getTime();
    }

    /**
     * 判断是否是需要的时间格式
     *
     * @param date
     * @param format
     * @return
     */
    public static boolean checkDate(String date, String format) {
        DateFormat df = new SimpleDateFormat(format);
        Date d = null;
        try {
            d = df.parse(date);
        } catch (Exception e) {
            //如果不能转换,肯定是错误格式
            return false;
        }
        String s1 = df.format(d);
        // 转换后的日期再转换回String,如果不等,逻辑错误.如format为"yyyy-MM-dd",date为
        // "2006-02-31",转换为日期后再转换回字符串为"2006-03-03",说明格式虽然对,但日期
        // 逻辑上不对.
        return date.equals(s1);
    }

    //进行时间比较
    public static int checkDatetime(Date time) {
        //当前时间
        String beginTime = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        //token时间
        String endTime = DateUtils.format(time, "yyyy-MM-dd HH:mm:ss");
        int compareTo = 0;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date date1 = format.parse(beginTime);
            Date date2 = format.parse(endTime);
            compareTo = date1.compareTo(date2);
            return compareTo;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return compareTo;
    }

    public static String doubleByString(Double doubles) {
        if (doubles > 0) {
            int parameter = doubles.intValue();
            return String.valueOf(parameter);
        }
        return "";
    }

    /**
     * 获取银行卡后四位
     *
     * @param cardNum
     * @return
     */
    public static String getCardTailNum(String cardNum) {
        StringBuffer tailNum = new StringBuffer();
        if (cardNum != null) {
            int len = cardNum.length();
            for (int i = len - 1; i >= len - 4; i--) {
                tailNum.append(cardNum.charAt(i));
            }
            tailNum.reverse();
        }
        return tailNum.toString();

    }

    public static BigDecimal Doubleadd(double v1, double v2, double v3) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        BigDecimal b3 = new BigDecimal(Double.toString(v3));
        return b1.add(b2).add(b3);
    }

    public static BigDecimal addDouble(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }

    public static BigDecimal addDouble(BigDecimal v1, double v2) {
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return v1.add(b2);
    }

    public static String getIntByString(int size) {
        DecimalFormat df1 = new DecimalFormat("000");//如果小于100就用他
        return df1.format(size);
    }

    /**
     * String转Bigdecimal
     */
    public static BigDecimal getByBigdecimal(String s) {
        BigDecimal b = new BigDecimal(s);
        b = b.setScale(2, BigDecimal.ROUND_DOWN); //小数位 直接舍去
        return b;
    }

    /**
     * 两个日期的比较
     */
    public static Integer getByDate(Date begin, Date end) {
        DateFormat format = new SimpleDateFormat(DEFAULT);
        //开始日期
        String nowDate = format.format(begin);
        //结束日期
        String maxDate = format.format(end);
        if (maxDate.compareTo(nowDate) > 0) {
            System.out.println("结束日期大于开始日期");
            return 1;
        } else if (maxDate.compareTo(nowDate) < 0) {
            System.out.println("结束日期小与开始日期");
            return 2;
        } else {
            System.out.println("结束日期等于开始日期");
            return 3;

        }
    }


    public static long getDateValid(Date dateStart, Date dateStop) {
        //毫秒ms
        long diff = dateStop.getTime() - dateStart.getTime();
        return diff;
    }

    public static String getWeekWorkds(int week) {
        return WEEK_DAY[week - 1];
    }

    public static String getCurrentDate() {
        return yyyyMMddHHmmss.get().format(new Timestamp(System.currentTimeMillis()));
    }

    public static String formatFromTimestamp(Timestamp date) {
        return yyyyMMddHHmmss.get().format(date);
    }

    public static String format(Timestamp date) {
        return yyyyMMdd.get().format(date);
    }

    public static Timestamp getCurrentTimeStamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    public static String getCurrentYyyy_mm_dd() {
        return yyyy_MM_dd.get().format(new Timestamp(System.currentTimeMillis()));
    }

    public static String getCurrentyyyyMMdd() {
        return yyyyMMdd.get().format(new Timestamp(System.currentTimeMillis()));
    }

    public static int getDayOfWeek(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            return 7;
        } else {
            return dayOfWeek - 1;
        }
    }

    public static long getTimeOfDay(String time) {
        String[] split = time.split(":");
        long timeOfDay = Long.valueOf(split[0]) * 3600000 + Long.valueOf(split[1]) * 60000;
        if (split.length == 3) {
            timeOfDay += Long.valueOf(split[2]) * 1000;
        }
        return timeOfDay;
    }

    public static String toTimeOfDay(long time) {
        long hour = time / 3600000;
        long minute = (time - hour * 3600000) / 60000;
        long second = (time - hour * 3600000 - minute * 60000) / 1000;
        StringBuilder sb = new StringBuilder();
        sb.append(hour).append(":").append(minute);
        if (second != 0) {
            sb.append(":").append(second);
        }
        return sb.toString();
    }

    public static long getTimeOfDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY) * 3600000 + calendar.get(Calendar.MINUTE) * 60000 + calendar.get(Calendar.SECOND) * 1000 + calendar.get(Calendar.MILLISECOND);
    }

    public static Long toSecondSign(Date time) {
        if (time == null) {
            return null;
        }
        return time.getTime() / 1000;
    }

    public static Date fromSecondSign(Integer time) {
        if (time == null) {
            return null;
        }
        return new Date(time * 1000L);
    }

    public static Date fromSecondSign(Long time) {
        if (time == null) {
            return null;
        }
        return new Date(time * 1000);
    }

    public static Timestamp addHoursOfTimeStamp() {
        Long duration = tokenHours;
        return new Timestamp(DateUtils.getCurrentTimeStamp().getTime() + duration);
    }

    public static Timestamp addHoursOfTimeStamp(int hours) {
        Long duration = 60 * 60 * 1000L * hours;
        return new Timestamp(DateUtils.getCurrentTimeStamp().getTime() + duration);
    }

    public static Timestamp addSecondOfTimeStamp(int second) {
        Long duration = (60 * second) * 1000L;
        return new Timestamp(DateUtils.getCurrentTimeStamp().getTime() + duration);
    }

    public static String getDateStartStr(String dateStart) {
        Date date = null;
        try {
            date = yyyyMMdd.get().parse(dateStart);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
    }

    public static String getYearAfter(int num) {
        LocalDate today = LocalDate.now();
        LocalDate afterYear = today.plus(num, ChronoUnit.YEARS);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        return afterYear.format(formatter);
    }

    public static String getYearAfterAndDay(int num) {
        LocalDate today = LocalDate.now();
        int day = num == 0 ? 0 : -1;
        LocalDate afterYear = today.plus(num, ChronoUnit.YEARS).plus(day, ChronoUnit.DAYS);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        return afterYear.format(formatter);
    }

    public static Date getYearAfterDate(int num) {
        LocalDate today = LocalDate.now();
        int day = num == 0 ? 0 : -1;
        LocalDate afterYear = today.plus(num, ChronoUnit.YEARS).plus(day, ChronoUnit.DAYS);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = afterYear.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    public static Timestamp getMonthStart(String dateStart) {
        Date date = null;
        try {
            date = yyyyMM.get().parse(dateStart);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取昨天的日期
     *
     * @return 昨天的日期
     */
    public static Date getYesterday() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.HOUR_OF_DAY, -24);
        return calendar.getTime();
    }

    public static Date getYesterday(Date today) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.HOUR_OF_DAY, -24);
        return calendar.getTime();
    }

    /**
     * 获取昨天的日期
     *
     * @return 昨天的末尾日期
     */
    public static Date getYesterEndday() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(getYesterday());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();

    }

    public static String getYyyyMMdd(Date date, boolean dayEnd, boolean dayStart) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        if (dayStart) {
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            calendar.set(Calendar.MINUTE, 00);
            calendar.set(Calendar.SECOND, 00);
            return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
        }
        if (dayEnd) {
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
        }
        return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
    }

    public static String getThisYearStartYyyyMm() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return yyyyMM.get().format(calendar.getTimeInMillis());
    }

    public static String getThisYearEndYyyyMm() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH, 12);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return yyyyMM.get().format(calendar.getTimeInMillis());
    }

    public static String getYyyyMMddMonthAfter(Date date, boolean dayEnd, boolean dayStart) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, 1);
        if (dayStart) {
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            calendar.set(Calendar.MINUTE, 00);
            calendar.set(Calendar.SECOND, 00);
            return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
        }
        if (dayEnd) {
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
        }
        return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
    }

    public static String getYyyyMMddMonthBefore(Date date, boolean dayEnd, boolean dayStart) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH, -1);
        if (dayStart) {
            calendar.set(Calendar.HOUR_OF_DAY, 00);
            calendar.set(Calendar.MINUTE, 00);
            calendar.set(Calendar.SECOND, 00);
            return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
        }
        if (dayEnd) {
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
        }
        return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
    }

    public static String getMonthAfterNum(String dateStart, int num) {
        Calendar calendar = Calendar.getInstance();
        Date date = null;
        try {
            date = yyyyMM.get().parse(dateStart);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        assert date != null;
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, num);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return yyyyMM.get().format(calendar.getTimeInMillis());
    }

    public static String getMonthBeforeNum(String dateStart, int num) {
        Calendar calendar = Calendar.getInstance();
        Date date = null;
        try {
            date = yyyyMM.get().parse(dateStart);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        assert date != null;
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -num);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return yyyyMM.get().format(calendar.getTimeInMillis());
    }

    public static String getThisYearMonth() {
        Calendar calendar = Calendar.getInstance();
        Date date = new Date();
        calendar.setTime(date);
        return yyyyMM.get().format(calendar.getTimeInMillis());
    }

    public static String getThisMonth() {
        Calendar calendar = Calendar.getInstance();
        Date date = new Date();
        calendar.setTime(date);
        return MM.get().format(calendar.getTimeInMillis());
    }

    public static String getDataMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return MM.get().format(calendar.getTimeInMillis());
    }

    /**
     * 当前季度的开始时间
     *
     * @return
     */
    public static String getCurrentQuarterStartTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 0);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 3);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 4);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 9);
            }
            c.set(Calendar.DATE, 1);
            return yyyyMM.get().format(c.getTimeInMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 当前季度的结束时间
     *
     * @return
     */
    public static String getCurrentQuarterEndTime() {
        Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            return yyyyMM.get().format(c.getTimeInMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String get3MonthStart(String startYearMonth) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Calendar bef = Calendar.getInstance();
        Calendar aft = Calendar.getInstance();
        Calendar calendar = Calendar.getInstance();
        try {
            aft.setTime(sdf.parse(startYearMonth));
            calendar.setTime(sdf.parse(startYearMonth));
        } catch (Exception e) {
            e.printStackTrace();
        }
        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
        int totalMonth = Math.abs(month + result);
        calendar.add(Calendar.MONTH, totalMonth / 3);
        return yyyyMM.get().format(calendar.getTimeInMillis());
    }

    public static String getDateEndStr(String dateEnd) {
        Date date = null;
        try {
            date = yyyyMMdd.get().parse(dateEnd);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return yyyyMMddHHmmss.get().format(calendar.getTimeInMillis());
    }

    public static Timestamp getMonthEnd(String dateEnd) {
        Date date = null;
        try {
            date = yyyyMM.get().parse(dateEnd);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, 1);
        calendar.roll(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return new Timestamp(calendar.getTimeInMillis());
    }

    public static Timestamp getDateStart(Date dateStart) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateStart);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    public static Timestamp getDateEnd(Date dateEnd) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dateEnd);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取当月所有天
     *
     * @return
     */
    public static List<Integer> getDayListOfMonth() {
        Calendar aCalendar = Calendar.getInstance();
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        List<Integer> list = new ArrayList<>(day);
        for (int i = 1; i <= day; i++) {
            list.add(i);
        }
        return list;
    }

    public static boolean compareHalfHourDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        //前面设置的时间-1
        calendar.add(Calendar.MINUTE, -30);
        Date halfHour = calendar.getTime();
        return date.getTime() > halfHour.getTime();
    }

    /**
     * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
     *
     * @param nowTime   当前时间
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     * @author zws
     */
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);

        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);

        Calendar end = Calendar.getInstance();
        end.setTime(endTime);

        return date.after(begin) && date.before(end);
    }

    public static Date getDataStrToData(String dataStr) throws ParseException {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return format.parse(dataStr);
        } catch (ParseException e) {
            throw e;
        }
    }

    public static String getYYYY(Date date) {
        return yyyy.get().format(date);
    }

    public static String getMM(Date date) {
        return MM.get().format(date);
    }

    public static String getDD(Date date) {
        return dd.get().format(date);
    }

    public static String getDifTimeByHour(Date nowDate, Date endDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        long sec = diff % nd % nh % nm / ns;
        return (hour < 10 ? "0" + hour : hour) + ":" + (min < 10 ? "0" + min : min) + ":" + (sec < 10 ? "0" + sec : sec);
    }

    public static List<String> getDayList(Date startTime, Date endTime) {
        List<String> dayList = new ArrayList<>();
        //倒序
        for (Date time = endTime;
             DateUtils.addDayOfDate(time, 1).getTime() > startTime.getTime();
             time = DateUtils.addDay(DateUtils.format(time), -1)) {
            dayList.add(DateUtils.format(time, DateUtils.DEFAULT));
        }
        return dayList;
    }

    public static List<String> getMonthList(Date startTime, Date endTime) {
        List<String> monthList = new ArrayList<>();
        if (ToolUtil.isEmpty(startTime)) {
            startTime = DateUtils.parse2Date("2022-03-01", DateUtils.YYYYMMDD);
        }
        //倒序
        for (Date time = endTime;
             DateUtils.getMonthStart(DateUtils.format(time)).getTime() >= DateUtils.getMonthStart(DateUtils.format(startTime)).getTime();
             time = DateUtils.addMonth(time, -1)) {
            monthList.add(DateUtils.format(time, DateUtils.YYYYMM));
        }
        return monthList;
    }

    /**
     * 获取上下半月
     * getHalfOfTheMonthInfo(DateUtils.getMonthStart("2021-10"));
     *
     * @param endDay
     * @return
     */
    public static List<HalfDateInfoResult> getHalfOfTheMonthInfo(Date endDay) {
        List<HalfDateInfoResult> results = new ArrayList<>();
        for (Date day = new Date();
             day.getTime() > endDay.getTime();
             day = DateUtils.addMonth(day, -1)) {
            HalfDateInfoResult result1 = new HalfDateInfoResult();
            String monthStr = DateUtils.format(day, DateUtils.YYYYMM);
            result1.setHalfDayInfoName(DateUtils.format(day, DateUtils.CHN_YM) + "下半月");
            result1.setSdate(DateUtils.addDayOfDate(DateUtils.getMonthStart(monthStr), 15));
            result1.setEdate(DateUtils.getMonthEnd(monthStr));
            results.add(result1);
            HalfDateInfoResult result2 = new HalfDateInfoResult();
            result2.setHalfDayInfoName(DateUtils.format(day, DateUtils.CHN_YM) + "上半月");
            result2.setSdate(DateUtils.getMonthStart(monthStr));
            result2.setEdate(DateUtils.getDateEnd(DateUtils.addDayOfDate(DateUtils.getMonthStart(monthStr), 14)));
            results.add(result2);
        }
        System.out.println(JSON.toJSONString(results));
        return results;
    }

//    public static void main(String[] args) {
//        getHalfOfTheMonthInfo(DateUtils.getMonthStart("2022-02"));
//    }
}
